using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Microsoft.Practices.Composite.Events;
using Silverlight.Weblog.Client.CoreBL.Events;
using Silverlight.Weblog.Client.DAL.Events;
using Silverlight.Weblog.Client.DAL.ViewModel;
using Silverlight.Weblog.Client.Default.Widgets.ViewModels;
using Silverlight.Weblog.Common.IoC;
using Silverlight.Weblog.Server.DAL;
using System.Linq;

namespace Silverlight.Weblog.Client.Default.Widgets
{
    public class MultipleBlogPostWidgetViewModel : ViewModelBase, IMultipleBlogPostWidgetViewModel, IDisposable
    {
        public MultipleBlogPostWidgetViewModel()
        {
            IoC.Get<IEventAggregator>().GetEvent<LoadBlogPostsHTMLEvent>().Subscribe(UpdateViewModel);
            IoC.Get<IEventAggregator>().GetEvent<InitiaPayloadLoadedEvent>().Subscribe(UpdateViewModel);
            IoC.Get<IEventAggregator>().GetEvent<GoToBlogPostEvent>().Subscribe(UpdateViewModelGoToBlogPostEvent);
            IoC.Get<IEventAggregator>().GetEvent<GoToBlogPostsEvent>().Subscribe(UpdateViewModel_GoToBlogPostsEvent);
        }

        public void UpdateViewModel_GoToBlogPostsEvent(List<BlogPost> obj)
        {
            Model = obj;
            UpdateCachedViewModelsWithServerModels();
            RaisePropertyChanged((MultipleBlogPostWidgetViewModel vm) => vm.ChildViewModels);
        }

        public void UpdateViewModelGoToBlogPostEvent(BlogPost obj)
        {
            Model = null;
            _childViewModels.Clear();
            RaisePropertyChanged((MultipleBlogPostWidgetViewModel vm) => vm.ChildViewModels);
        }

        public void UpdateViewModel(User obj)
        {
            if (obj.Posts.Count > 1)
            {
                Model = obj.Posts.ToList();
                UpdateCachedViewModelsWithServerModels();
                RaisePropertyChanged((MultipleBlogPostWidgetViewModel vm) => vm.ChildViewModels);

            }
            else
            {
                Model = null;
                _childViewModels.Clear();
                RaisePropertyChanged((MultipleBlogPostWidgetViewModel vm) => vm.ChildViewModels);

            }
        }

        private void UpdateCachedViewModelsWithServerModels()
        {
            foreach (var ServerBlogPost in Model)
            {
                var CorrespondingServerBlogPost =
                    _childViewModels.FirstOrDefault(b => b.Model.Permlink == ServerBlogPost.Permlink
                                                 && b.Model.IsInitializedByHtmlPayload);
                if (CorrespondingServerBlogPost != null)
                {
                    CorrespondingServerBlogPost.Model = ServerBlogPost;
                }
            }

            var removeFromCache = new List<MultipleBlogPostItemViewModel>();
            foreach (var cachedViewModel in _childViewModels)
            {
                if (!Model.Any(b => b.Permlink == cachedViewModel.Model.Permlink))
                    removeFromCache.Add(cachedViewModel);
            }
            foreach (MultipleBlogPostItemViewModel blogPost in removeFromCache)
                _childViewModels.Remove(blogPost);
        }

        public void UpdateViewModel(List<BlogPost> obj)
        {
            Model = obj;
            RaisePropertyChanged((MultipleBlogPostWidgetViewModel vm) => vm.ChildViewModels);
        }

        #region Model
        private List<BlogPost> _model;
        public List<BlogPost> Model
        {
            get { return _model; }
            set
            {
                if (_model != value)
                {
                    _model = value;
                    RaisePropertyChanged("Model");

                    if (_model != null)
                    {
                        View.IsActive = true;
                    }
                }

            }
        }
        #endregion Model

        private ObservableCollection<MultipleBlogPostItemViewModel> _childViewModels = new ObservableCollection<MultipleBlogPostItemViewModel>();
        public ObservableCollection<MultipleBlogPostItemViewModel> ChildViewModels
        {
            get
            {
                if (Model != null)
                {
                    foreach (BlogPost post in Model)
                    {
                        if (!_childViewModels.Any(c => c.Model == post))
                        {
                            var ReturnValue = new MultipleBlogPostItemViewModel();
                            ReturnValue.UpdateViewModel(post);
                            _childViewModels.Add(ReturnValue);
                        }
                    }
                }
                return _childViewModels;
            }
        }


        #region Implementation of IDisposable

        public void Dispose()
        {
            IoC.Get<IEventAggregator>().GetEvent<LoadBlogPostsHTMLEvent>().Unsubscribe(UpdateViewModel);
        }

        #endregion
    }
}